/**
 * 启动后会扫描两个文件夹路径中的图片是否一致，不一致则压缩原图
 * 配置在config.js中
 */
const rimraf = require('rimraf');
const chokidar = require('chokidar');
const path = require('path');
const express = require('express');
const fs = require('fs');

const ImageProcessor = require('./ImageProcessor');
const config = require('./config');
const ip = new ImageProcessor(config);
const app = express();
const input = path.resolve(config.inputDir);
const output = path.resolve(config.outputDir);

// 单个文件
// ip.processImage('./input/image.png', './output/image1.png').then(e=>{
//     console.log("单文件处理完成!", e)
// })

// 启动时扫描
scanfDirectory(10 * 60 * 1000, config.scanTimeStep, ()=>{
    // 扫描整个目录
    ip.processDirectory().then(e=>{
        console.log("目录处理完成!", ip.inputDir, "=>" , ip.outputDir)
    });
});
if(config.watchDir) {
    watchImageProcessor(ip, config);
}


app.get('*', readImg);
app.post('*', readImg);
app.listen(config.prot, () => {
    console.log('服务启动完成，端口: ' + config.port);
});

/**
 * 
 * @param {Number} logStep 日志显示时间
 * @param {Number} scanStep 扫描间隔时间
 * @param {Function} fun 要执行的函数
 */
function scanfDirectory(logStep, scanStep, fun) {
    // 启动时扫描
    fun();

    let nextLogTime = Date.now() + logStep;
    let nextScanTime = Date.now() + scanStep;
    // 定时扫描
    let intId =  setInterval(()=>{
        let dn = Date.now();
        if(nextScanTime < dn) {
            fun();
        } else {
            if(nextLogTime < dn) {
                console.log(`下次刷新时间还剩：${parseInt((nextScanTime - dn) / 1000)}s`);
            }
        }
    }, 5000);
}
function watchImageProcessor(ip, conf) {
    let baseDir = path.join(conf.inputDir);
    // 初始化 Chokidar 观察器
    const watcher = chokidar.watch(conf.inputDir, {
        ignored: /(^|[\/\\])\../, // 忽略 .dotfiles
        persistent: true, // 是否保持程序持续运行
        ignoreInitial: true, // 是否忽略初始化时已经存在的文件
        followSymlinks: true, // 跟随符号链接
        depth: 0, // 0 表示无限制，监视所有子目录
    });
    // 添加事件监听器
    // watcher.on('add', (path) => { console.log(`文件 ${path} 已被添加`); }) // 新增文件或目录
    // watcher.on('unlink', (path) => { console.log(`文件 ${path} 已被删除`); }) // 删除文件或目录
    // watcher.on('addDir', (path) => { console.log(`目录 ${path} 已被新建`); }) // 新增目录
    // watcher.on('unlinkDir', (path) => { console.log(`目录 ${path} 已被删除`); }) // 删除目录;

    // 新增文件或目录
    watcher.on('add', (filepath) => { 
        const relativePath = filepath.replace(baseDir, "");
        const outFile = path.join(conf.outputDir, relativePath);
        ip.processImage(filepath, outFile).then(e=>{
            console.log(relativePath + " 新文件处理完成!", e || "");
        });
    })
    // 新增目录
    watcher.on('addDir', (filepath) => {
        const relativePath = filepath.replace(baseDir, "");
        const outFile = path.join(conf.outputDir, relativePath);
        ip.processDirectory(filepath, outFile).then(e=>{
            console.log(relativePath + " 新文件夹处理完成!", e || "");
        });
    })

    // 删除文件或目录
    watcher.on('unlink', (filepath) => { 
        const relativePath = filepath.replace(baseDir, "");
        const outPath = path.join(conf.outputDir, relativePath);
        rimraf.moveRemove(outPath).then(() => console.log(outPath + '文件已成功删除（或原本就不存在）'))
            .catch((err) => console.error('删除过程中发生了错误:', err));
    })
    // 删除目录
    watcher.on('unlinkDir', (filepath) => { 
        const relativePath = filepath.replace(baseDir, "");
        const outPath = path.join(conf.outputDir, relativePath);
        rimraf.moveRemove(outPath).then(() => console.log(outPath + '目录已成功删除（或原本就不存在）'))
            .catch((err) => console.error('删除过程中发生了错误:', err));
    })
}

/**
 * 读取图片
 * @param {Request} req 
 * @param {Response} res 
 */
function readImg(req, res){
    // 获取get和post的参数
    let body = {...req.query, ...req.body};
    let imagePath = req.originalUrl.split("?")[0];

    let find, filepath = path.join(output, imagePath);
    if(!body.raw) {
        // 先查找压缩图片
        try{
            find = fs.statSync(filepath).isFile();
        }catch(e){
            if (e.code != 'ENOENT') {
                console.log("查找压缩图片异常", e.message)
            }
        }
    }
    if(!find) {
        try{
            filepath = path.join(input, imagePath);
            find = fs.statSync(filepath).isFile();
        }catch(e){
            if (e.code != 'ENOENT') {
                console.log("查找普通图片异常", e.message)
            }
        }
    }
    if(find) {
        // 使用res.sendFile发送图片
        res.sendFile(filepath);
    } else{
        res.status(404).send(config.fileNotFound);
    }
}